package com.syt.mina.handler;

import java.util.List;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;

import com.syt.mina.handler.service.HandlerAdapter;
import com.syt.mina.handler.service.HandlerInterceptor;
import com.syt.mina.handler.service.HandlerMapping;
import com.syt.mina.session.DefaultSessionManager;
import com.syt.mina.session.ISessionManager;




public class DispacherHandler extends IoHandlerAdapter {
	
	private List<HandlerMapping> handlerMappings;
	
	private List<HandlerAdapter> handlerAdapters;
	
	private ISessionManager sessionManager = new DefaultSessionManager();
	
	
	public DispacherHandler(){
	}
	
	
	@Override
    public void sessionOpened(IoSession session) throws Exception{
		sessionManager.addSession(session);
    }
	
    @Override
    public void messageReceived(IoSession session, Object message) {
    	
    	if(sessionManager.isDispach(session, message)){
    		doDispatch(session,message);
    	}
    }
    
    @Override
    public void sessionClosed(IoSession session)throws Exception {
    	sessionManager.deleteSession(session);
    }
    @Override
	public void exceptionCaught(IoSession session, Throwable cause)
	    throws Exception {
    	sessionManager.exceptionCaught(session, cause);
	}
	
    
    protected void doDispatch(IoSession session, Object message){
    	HandlerExecutionChain mappedHandler = null;
    	try {
			mappedHandler = getHandler(session,message);
			HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
			HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();
			if (interceptors != null) {
				for (int i = 0; i < interceptors.length; i++) {
					HandlerInterceptor interceptor = interceptors[i];
					if (!interceptor.preHandle(session, message, mappedHandler.getHandler())) {
						return;
					}
				}
			}

			// Actually invoke the handler.
			ha.handle(session, message, mappedHandler.getHandler());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    
    public List<HandlerMapping> getHandlerMappings() {
		return handlerMappings;
	}


	public void setHandlerMappings(List<HandlerMapping> handlerMappings) {
		this.handlerMappings = handlerMappings;
	}


	public List<HandlerAdapter> getHandlerAdapters() {
		return handlerAdapters;
	}


	public void setHandlerAdapters(List<HandlerAdapter> handlerAdapters) {
		this.handlerAdapters = handlerAdapters;
	}


	protected HandlerExecutionChain getHandler(IoSession session, Object message)throws Exception {
		for (HandlerMapping hm : this.handlerMappings) {
			HandlerExecutionChain handler = hm.getHandler(session,message);
			if (handler != null) {
				return handler;
			}
		}
		return null;
	}
    
	protected HandlerAdapter getHandlerAdapter(Object handler)  {
		for (HandlerAdapter ha : this.handlerAdapters) {
			if (ha.supports(handler)) {
				return ha;
			}
		}
		//TODO throw Exception
		return null;
	}

    public void preMessageReceivedHandler(IoSession session, Object message){
    	
    }
    
    public void afterMessageReceivedHandler(IoSession session, Object message){
    	
    }


	public ISessionManager getSessionManager() {
		return sessionManager;
	}


	public void setSessionManager(ISessionManager sessionManager) {
		this.sessionManager = sessionManager;
	}

}
